package com.pine.dbant.common.plugin.meta.function.jdbc;

import com.google.common.collect.Sets;
import com.pine.dbant.common.model.JdbcMetadataTreeView;
import com.pine.dbant.common.plugin.meta.*;
import com.pine.sunflower.core.utils.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author xiaoyuan
 * @create 2022/12/27 9:32
 **/
@Slf4j
public class CatalogFunction extends AbstractQueryMetadataFunction<JdbcMetadataAnalysisConfig, List> {

    protected static final String TABLE_CAT = "TABLE_CAT";

    public CatalogFunction(String type) {
        super(type);
    }

    @Override
    public List<MetadataNode> doQuery(JdbcMetadataAnalysisConfig metadataAnalysisConfig, QueryMetadataParam queryMetadataParam) {
        DatabaseMetaData dbMetaData;
        try {
            dbMetaData = metadataAnalysisConfig.getConnection().getMetaData();
        } catch (SQLException e) {
            throw new JdbcMetaAnalysisException(e.getMessage(), e);
        }
        Set<String> catalogs = Sets.newConcurrentHashSet();
        List<MetadataNode> metadataNodes = new ArrayList<>();
        try (ResultSet rs = dbMetaData.getCatalogs()) {
            while (rs.next()) {
                String catalog = rs.getString(TABLE_CAT);
                if (StringUtils.isEmpty(catalog)) {
                    log.warn("忽略为空的catalog");
                    continue;
                }
                if (filterCatalog(metadataAnalysisConfig.getMetaAnalysisFilter(), catalog)) {
                    log.warn("忽略在拦截器中过滤的catalog[{}]", catalog);
                    continue;
                }
                catalogs.add(catalog);
            }
        } catch (SQLException e) {
            log.error("获取该数据源的所有数据库catalog错误", e);
            throw new JdbcMetaAnalysisException("获取该数据源的所有数据库catalog错误", e);
        }
        metadataNodes.addAll(catalogs.stream()
                .map(dbName -> new DefaultMetadataNode().setName(dbName)
                                .setId(Strings.format("{}_{}", metadataAnalysisConfig.getConnectionInfo().getId(), dbName))
                                .setType(JdbcMetadataTreeView.CATALOG.getType())
//                        .setParentId(String.valueOf(metadataAnalysisConfig.getConnectionInfo().getId()))
                                .addProperty(CONN_ID, metadataAnalysisConfig.getConnectionInfo().getId())
                                .addProperty(CATALOG, dbName)
                ).collect(Collectors.toList()));
        return metadataNodes;
    }

    /**
     * 过滤是否在白名单中的catalog
     *
     * @param catalog
     * @return
     */
    protected boolean filterCatalog(MetaAnalysisFilter filter, String catalog) {
        return filter.checkIgnoreCatalog(catalog);
    }
}
